
import axios from "axios"
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { ElMessage } from "element-plus"
import { config } from '@/config/axios/config'
import { useI18n } from '@/hooks/web/useI18n'
import { Result } from "../processingStatus"
import Logger from "@/utils/Logger"



// 处理响应状态错误
enum HttpStatusCode {
  BadRequest = 400,
  Unauthorized = 401,
  Forbidden = 403,
  NotFound = 404,
  MethodNotAllowed = 405,
  RequestTimeout = 408,
  InternalServerError = 500,
  ServiceUnavailable = 503,
  GatewayTimeout = 504
}

// 处理响应错误处理
const handleResponseError = (error: any): string => {
  
  const { code } = error
  const {t} = useI18n()
  if(!window.navigator.onLine || code === 'ERR_NETWORK') {
    return t("sys.api.networkExceptionMsg")
  }
  const {status} =error.response
  switch (status) {
    case HttpStatusCode.BadRequest:
      return t("sys.api.apiRequestFailed")
    case HttpStatusCode.Unauthorized:
      return t('sys.api.errMsg401')
    case HttpStatusCode.Forbidden:
      return t('sys.api.errMsg403')
    case HttpStatusCode.NotFound:
      return t('sys.api.errMsg404')
    case HttpStatusCode.MethodNotAllowed:
      return t('sys.api.errMsg405')
    case HttpStatusCode.RequestTimeout:
      return t('sys.api.errMsg408')
    case HttpStatusCode.InternalServerError:
      return t('sys.api.errMsg500')
    case HttpStatusCode.ServiceUnavailable:
      return t('sys.api.errMsg503')
    case HttpStatusCode.GatewayTimeout:
      return t('sys.api.errMsg504')
    default:
      return `${t('sys.api.errMsg505')} ${status}`
  }
}


// 导出httprequest
export class HttpRequest {
  // 实例
  instance: AxiosInstance
  // 基础配置
  baseConfig: AxiosRequestConfig = {}

  //构造函数
  constructor(config: AxiosRequestConfig) {
    // 初始化配置
    this.init()
    // 合并配置
    this.baseConfig = Object.assign(this.baseConfig, config)
    // 实例化axios
    this.instance = axios.create(this.baseConfig)

    // 定义请求拦截器
    this.instance.interceptors.request.use(
      (conf) => {
        console.log('请求拦截器', conf.data)
        return conf
      },
      (error: any) => {
        // 返回全局错误信息
        return Promise.reject(error)
      }
    )

    // 定义响应拦截器
    this.instance.interceptors.response.use(
      (res) => {
        return res
      },
      (error: any) => {
        // 返回全局错误信息
        const errorInfo = handleResponseError(error)
        ElMessage.error({
          message: `${errorInfo},请联系网络或系统管理员`,
          duration: 3000,
          type: 'error',
          showClose: true
        })
        return Promise.reject(error.response)
      }
    )
  }


  // 初始化请求
   init = () => {
     const {timeout,baseUrl } = config
     this.baseConfig.timeout = timeout
     this.baseConfig.baseURL  = baseUrl
     this.baseConfig.withCredentials = false
   }


  // 定义请求方法
  public httpRequest(options: AxiosRequestConfig): 
  Promise<AxiosResponse> {
    return this.instance.request(options)
  }

  // 定义get方法
  public get<T =any>(url: string, conf?: AxiosRequestConfig)
  :Promise<Result<T>> {
    return new Promise((resolve) => {
      this.instance.get(url, conf)
      .then((res) => {
        const {data}=res
        resolve(data)
      }).catch((err) => this.handlerReqError(err))
    })
  }

  // 定义post方法
  public post<T =any>(url: string, data?: any, conf?: AxiosRequestConfig)
  :Promise<Result<T>> {
    return new Promise((resolve) => {
      this.instance.post(url, data, conf)
      .then((res) => {
        const {data} = res
        resolve(data)
      }).catch((err) => this.handlerReqError(err))
    })
  }

  // 定义put方法
  public put<T =any>(url: string, data?: any, conf?: AxiosRequestConfig)
  :Promise<Result<T>> {
    return new Promise((resolve) => {
      this.instance.put(url, data, conf)
      .then((res) => {
        const {data} = res
        resolve(data)
      }).catch((err) => this.handlerReqError(err))
    })
  }

  // 定义delete方法
  public delete<T =any>(url: string, conf?: AxiosRequestConfig)
  :Promise<Result<T>> {
    return new Promise((resolve) => {
      this.instance.delete(url, conf).then((res) => {
        const {data} = res
        resolve(data)
      }).catch((err) => this.handlerReqError(err))
    })
  }

  // 定义header方法
  public header<T=any>(url:string,conf?:AxiosRequestConfig)
  : Promise<Result<T>> {
    return new Promise((resolve) => {
      this.instance.head(url, conf)
      .then((res) => {
        const {data} = res
        resolve(data)
      }).catch((err) => this.handlerReqError(err))
    })
  }

  // 定义patch方法
   public patch<T =any>(url: string, data?: any, conf?: AxiosRequestConfig)
   :Promise<Result<T>> {
     return new Promise((resolve) => {
       this.instance.patch(url, data, conf)
       .then((res) => {
         const {data} = res
         resolve(data)
       }).catch((err) => this.handlerReqError(err))
     })
   }

   // 定义download方法
   public download(url: string, conf?: AxiosRequestConfig)
   :Promise<AxiosResponse> {
     return new Promise((resolve) => {
       this.instance.get(url, conf)
       .then((res) => {
         const {data} = res
         resolve(data)
       }).catch((err) => this.handlerReqError(err))
     })
   }

   // 定义upload方法
   public upload(url: string, data?: any, conf?: AxiosRequestConfig)
   :Promise<AxiosResponse> {
     return this.instance.post(url, data, conf)
   }

   // 统一处理请求错误日志
   handlerReqError(err:any) {
    if (!err) return
    const { config,data } =err
    Logger.prettyError(`请求${config?.url}异常：`,data)
   }

}

// 导出默认httpRequest 实例
export default new HttpRequest({})
